package com.foxchen.fanjingmontainticket.service.impl;

import com.foxchen.fanjingmontainticket.bean.HxBlankUserInfo;
import com.foxchen.fanjingmontainticket.service.HxBlankMoneyService;
import lombok.extern.slf4j.Slf4j;
import org.dromara.hutool.core.codec.binary.Base64;
import org.dromara.hutool.core.codec.binary.HexUtil;
import org.dromara.hutool.core.date.DateUtil;
import org.dromara.hutool.crypto.Mode;
import org.dromara.hutool.crypto.Padding;
import org.dromara.hutool.crypto.digest.mac.HMac;
import org.dromara.hutool.crypto.digest.mac.HmacAlgorithm;
import org.dromara.hutool.crypto.symmetric.AES;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

@Slf4j
@Service
public class HxBlankMoneyServiceImpl implements HxBlankMoneyService {
    private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(100);
    private static Map<String,String> CONFIG_MAP = new HashMap<>();
    private static final String IV = "0000000000000000";
    static {
        CONFIG_MAP.put("mainKey3600","47CB94B87D984551");
        CONFIG_MAP.put("aesKey3600","5D249023747AD177D6C5D2FB5E9A98745D771ED4906A292FDCEE6E57F1EC9D5A");
        CONFIG_MAP.put("hmd5Key3600","057E68C3E69B30668D851FFC1AEA1975B7DA3C4E648472C7D1BB35E77A44C959");
        CONFIG_MAP.put("head_osnumber3600","1e68f1a8cf-19a1f-1d23b-1a24c-16e671f36d11afd");
    }


    public boolean begin(List<HxBlankUserInfo> userInfoList) throws Exception {
        boolean execute = false;
        while (!execute) {
            // 并行执行
            List<Future<HxBlankUserInfo>> futureList = userInfoList
                    .stream()
                    .map(userInfo -> EXECUTOR_SERVICE.submit(() -> {

                        return userInfo;
                    }))
                    .toList();

            // 等待所有线程执行完
            for (Future<HxBlankUserInfo> future : futureList) {
                HxBlankUserInfo user = future.get();
                log.info("execute user:{},result:{}",user.getIdCard(),user.getSuccess());
            }

            // 筛选是否全部执行成功
            execute = userInfoList.stream().anyMatch(HxBlankUserInfo::getSuccess);
        }

        return Boolean.TRUE;
    }

    private void getMoney(HxBlankUserInfo hxBlankUserInfo) {
        String nowTime = DateUtil.format(new Date(), "yyyyMMddHHmmss");

    }


    private Map<String,String> encrypt(String timeNow){
        Map<String,String> params = new HashMap<>();
        params.put("head_jsessionid","");
        params.put("h5_channel_id","006");
        params.put("head_area_code","110000");
        params.put("head_iv","0000000000000000");
        params.put("head_osnumber",CONFIG_MAP.get("head_osnumber3600"));
        params.put("system_id","hxmark");
        params.put("request_time",timeNow);
        params.put("head_trans_code","100104");

        List<String> signWords = new ArrayList<>(Arrays.asList("head_jsessionid", "act_id", "is_prize", "request_time"));

        String hmd5Key = aesDecryptString(CONFIG_MAP.get("hmd5Key3600"),CONFIG_MAP.get("mainKey3600"));

        String headMac = signHmacMd5(params,hmd5Key,signWords);
        log.info("headMac:{}",headMac);

        String aesKey = aesDecryptString(CONFIG_MAP.get("aesKey3600"),CONFIG_MAP.get("mainKey3600"));
        List<String> encodeWords = new ArrayList<>(Arrays.asList("head_jsessionid", "act_id", "user_mobile", "phone", "is_prize", "login_name", "id_code", "card_no", "request_time", "user_name"));

        Map<String,String> encryptParams = (Map<String,String>)aesEncrypt(params, aesKey, encodeWords);
        encryptParams.put("head_mac",headMac);

        return encryptParams;
    }

    private String signHmacMd5(Map<String,String> params,String hmd5Key,List<String> signWords){
        String signString = "";
        List<String> lists = new ArrayList<>();

        for (String signWord : signWords) {
            Optional.ofNullable(params.get(signWord)).ifPresent(lists::add);
        }

        if(!lists.isEmpty()){
            signString = String.join(" ", lists);
        }

        return new HMac(HmacAlgorithm.HmacMD5, hmd5Key.getBytes()).digestHex(signString).toUpperCase();
    }

    private String aesDecryptString(String str,String key){
        // Hex -> byte[] -> Base64
        byte[] cipherBytes = HexUtil.decode(str);
        String base64Cipher = Base64.encode(cipherBytes);

        // 初始化 AES（CBC 模式 + PKCS5Padding）
        AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, key.getBytes(StandardCharsets.UTF_8), IV.getBytes(StandardCharsets.UTF_8));

        // 解密
        return aes.decryptStr(base64Cipher);
    }

    private Object aesEncrypt(Object params,String aesKey,List<String> encodeWords) {
        if(params instanceof String){
            return aesEncryptString((String) params, aesKey);
        }

        Map<String,String> paramsMap = (Map<String,String>) params;
        for (String key : encodeWords) {
            String data = paramsMap.get(key);
            if(data != null){
                data = aesEncryptString(data, aesKey);
                paramsMap.put(key, data);
            }
        }
        return params;
    }

    private String aesEncryptString(String params,String aesKey){
        // 初始化 AES（CBC 模式 + PKCS5Padding）
        AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, aesKey.getBytes(StandardCharsets.UTF_8), IV.getBytes(StandardCharsets.UTF_8));
        return aes.encryptHex(params).toUpperCase();
    }
}
